/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

#include "../facecat/stdafx.h"
#include "QtHost.h"
#include "RibbonButton.h"
#include "QtPaint.h"

namespace FaceCat{
	ScrollButtonM::ScrollButtonM() {
		m_arrowType = 0;
	}

	ScrollButtonM::~ScrollButtonM() {

	}

	void ScrollButtonM::onPaint(FCPaint* paint, const FCRect& clipRect) {
		int width = getWidth(), height = getHeight();
		if (width > 0 && height > 0)
		{
			FCRect drawRect = { 0, 0, width, height };
			if (m_arrowType == 5)
			{
				if (this == m_native->getPushedView() || this == m_native->getHoveredView())
				{
					paint->fillRoundRect(FCColor::rgb(42, 138, 195), drawRect, 4);
				}
				else
				{
					if (MyColor::getStyle() == 0) {
						paint->fillRoundRect(FCColor::rgb(100, 100, 100), drawRect, 4);
					}
					else {
						paint->fillRoundRect(FCColor::rgb(225, 225, 225), drawRect, 4);
					}
				}
			}
			else if (m_arrowType == 6)
			{
				if (this == m_native->getPushedView())
				{
					paint->fillRect(FCColor::rgba(0, 0, 0, 25), drawRect);
				}
			}
			else
			{
				if (allowDrag() && this == m_native->getPushedView())
				{
					paint->fillRect(FCColor::rgb(42, 138, 195), drawRect);
				}
				else
				{
					if (MyColor::getStyle() == 0) {
						paint->fillRect(FCColor::rgb(100, 100, 100), drawRect);
					}
					else {
						paint->fillRect(FCColor::rgb(220, 220, 220), drawRect);
					}
				}
			}
			if (this == m_native->getPushedView())
			{
				int mw = width / 2, mh = height / 2;
				FCPoint point1 = { 0 };
				FCPoint point2 = { 0 };
				FCPoint point3 = { 0 };
				int ts = 3;
				switch (m_arrowType)
				{
				case 1:
					point1.x = mw - ts;
					point1.y = mh;
					point2.x = mw + ts;
					point2.y = mh - ts * 3;
					point3.x = mw + ts;
					point3.y = mh + ts * 3;
					break;
				case 2:
					point1.x = mw + ts;
					point1.y = mh;
					point2.x = mw - ts;
					point2.y = mh - ts * 3;
					point3.x = mw - ts;
					point3.y = mh + ts * 3;
					break;
				case 3:
					point1.x = mw;
					point1.y = mh - ts;
					point2.x = mw - ts * 3;
					point2.y = mh + ts;
					point3.x = mw + ts * 3;
					point3.y = mh + ts;
					break;
				case 4:
					point1.x = mw;
					point1.y = mh + ts;
					point2.x = mw - ts * 3;
					point2.y = mh - ts;
					point3.x = mw + ts * 3;
					point3.y = mh - ts;
					break;
				}
				FCPoint points[3] = { 0 };
				points[0] = point1;
				points[1] = point2;
				points[2] = point3;
				paint->fillPolygon(FCColor::rgb(0, 0, 0), points, 3);
			}
		}
	}

	void ScrollButtonM::onPaintBorder(FCPaint* paint, const FCRect& clipRect) {

	}

    FCSize QtHost::getClientSize(){
        FCSize size = {0};
        if(m_native){
            size.cx = m_widget->width();
            size.cy = m_widget->height();
        }
        return size;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    QtHost::QtHost(){
		m_allowOperate = true;
		m_allowPartialPaint = true;
		m_invokeSerialID = 0;
		m_native = 0;
        m_objectItem = 0;
		m_pInvokeMsgID = 0x0401;
		m_toolTip = 0;
		m_touchPoint.x = 0;
		m_touchPoint.y = 0;
		m_virtualMode = false;
        m_widget = 0;
	}

    QtHost::~QtHost(){
        if (m_toolTip){
            m_native->removeView(m_toolTip);
            delete m_toolTip;
			m_toolTip = 0;
        }
        m_objectItem = 0;
        m_widget = 0;
        m_native = 0;
	}

    FCNative* QtHost::getNative(){
		return m_native;
	}

    void QtHost::setNative(FCNative *value){
		m_native = value;
	}

    int QtHost::getPInvokeMsgID(){
		return m_pInvokeMsgID;
	}

    void QtHost::setPInvokeMsgID(int value){
		m_pInvokeMsgID = value;
	}

    FCView* QtHost::getToolTip(){
		return m_toolTip;
	}

    void QtHost::setToolTip(FCView *value){
		m_toolTip = value;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    bool QtHost::allowOperate(){
		return m_allowOperate;
	}

    bool QtHost::allowPartialPaint(){
		return m_allowPartialPaint;
	}

    void QtHost::beginInvoke(FCView *view, Object args){
		int seraialID = 0;
		lock();
		m_invokeSerialID++;
		seraialID = m_invokeSerialID;
		m_invokeArgs[seraialID] = args;
		m_invokeViews[seraialID] = view;
        unLock();
	}

    void QtHost::copy(lstring text){
	}

    FCView* QtHost::createInternalView(FCView *parent, const String& clsid){
		FCCalendar* calendar = dynamic_cast<FCCalendar*>(parent);
		if (calendar) {
			if (clsid == L"datetitle") {
				return new DateTitle(calendar);
			}
			else if (clsid == L"headdiv") {
				HeadDiv* headDiv = new HeadDiv(calendar);
				headDiv->setWidth(parent->getWidth());
				headDiv->setDock(FCDockStyle_Top);
				return headDiv;
			}
			else if (clsid == L"lastbutton") {
				return new ArrowButton(calendar);
			}
			else if (clsid == L"nextbutton") {
				ArrowButton* nextBtn = new ArrowButton(calendar);
				nextBtn->setToLast(false);
				return nextBtn;
			}
		}
		FCSplitLayoutDiv* splitLayoutDiv = dynamic_cast<FCSplitLayoutDiv*>(parent);
		if (splitLayoutDiv) {
			if (clsid == L"splitter") {
				FCButton* splitter = new FCButton;
				splitter->setBackColor(FCColor_Border);
				splitter->setBorderColor(FCColor_Border);
				FCSize size = { 5, 5 };
				splitter->setSize(size);
				return splitter;
			}
		}
		FCScrollBar* scrollBar = dynamic_cast<FCScrollBar*>(parent);
		if (scrollBar) {
			scrollBar->setBackColor(FCColor_None);
			scrollBar->setBorderColor(FCColor_None);
			FCSize scrollBarSize = { 10, 10 };
			scrollBar->setSize(scrollBarSize);
			if (clsid == L"addbutton") {
				FCButton* addButton = new FCButton;
				FCSize size = { 0, 0 };
				if (dynamic_cast<FCHScrollBar*>(scrollBar)) {
					size.cy = 5;
				}
				else {
					size.cx = 5;
				}
				addButton->setSize(size);
				if (dynamic_cast<FCHScrollBar*>(scrollBar)) {
					//addButton->setArrowType(2);
				}
				else {
					//addButton->setArrowType(4);
				}
				return addButton;
			}
			else if (clsid == L"backbutton") {
				ScrollButtonM* backButton = new ScrollButtonM;
				backButton->setBackColor(FCColor_None);
				backButton->setBorderColor(FCColor_None);
				backButton->m_arrowType = 6;
				return backButton;
			}
			else if (clsid == L"scrollbutton") {
				ScrollButtonM* scrollButton = new ScrollButtonM;
				scrollButton->setAllowDrag(true);
				scrollButton->setBackColor(FCColor::rgba(94, 102, 115, 200));
				scrollButton->setBorderColor(FCColor_None);
				scrollButton->setCornerRadius(4);
				scrollButton->m_arrowType = 5;
				return scrollButton;
			}
			else if (clsid == L"reducebutton") {
				FCButton* reduceButton = new FCButton;
				FCSize size = { 0, 0 };
				if (dynamic_cast<FCHScrollBar*>(scrollBar)) {
					size.cy = 5;
				}
				else {
					size.cx = 5;
				}
				reduceButton->setSize(size);
				if (dynamic_cast<FCHScrollBar*>(scrollBar)) {
					//reduceButton->setArrowType(1);
				}
				else {
					//reduceButton->setArrowType(3);
				}
				return reduceButton;
			}
		}
		FCTabPage* tabPage = dynamic_cast<FCTabPage*>(parent);
		if (tabPage) {
			if (clsid == L"headerbutton") {
				FCButton* button = new FCButton;
				button->setAllowDrag(true);
				FCSize size = { 100, 20 };
				button->setSize(size);
				return button;
			}
		}
		FCComboBox* comboBox = dynamic_cast<FCComboBox*>(parent);
		if (comboBox) {
			if (clsid == L"dropdownbutton") {
				FCButton* dropDownButton = new FCButton;
				//dropDownButton->setArrowType(4);
				dropDownButton->setDisplayOffset(false);
				int width = comboBox->getWidth();
				int height = comboBox->getHeight();
				FCPoint location = { width - 16, 0 };
				dropDownButton->setLocation(location);
				FCSize size = { 16, height };
				dropDownButton->setSize(size);
				return dropDownButton;
			}
			else if (clsid == L"dropdownmenu") {
				FCComboBoxMenu* comboBoxMenu = new FCComboBoxMenu;
				comboBoxMenu->setComboBox(comboBox);
				comboBoxMenu->setPopup(true);
				FCSize size = { 100, 200 };
				comboBoxMenu->setSize(size);
				return comboBoxMenu;
			}
		}
		FCDateTimePicker* datePicker = dynamic_cast<FCDateTimePicker*>(parent);
		if (datePicker) {
			if (clsid == L"dropdownbutton") {
				FCButton* dropDownButton = new FCButton;
				//dropDownButton->setArrowType(4);
				dropDownButton->setDisplayOffset(false);
				int width = datePicker->getWidth();
				int height = datePicker->getHeight();
				FCPoint location = { width - 16, 0 };
				dropDownButton->setLocation(location);
				FCSize size = { 16, height };
				dropDownButton->setSize(size);
				return dropDownButton;
			}
			else if (clsid == L"dropdownmenu") {
				FCMenu* dropDownMenu = new FCMenu();
				FCPadding padding(1);
				dropDownMenu->setPadding(padding);
				dropDownMenu->setPopup(true);
				FCSize size = { 200, 200 };
				dropDownMenu->setSize(size);
				return dropDownMenu;
			}
		}
		FCSpin* spin = dynamic_cast<FCSpin*>(parent);
		if (spin) {
			if (clsid == L"downbutton") {
				FCButton* downButton = new FCButton;
				downButton->setText(L"-");
				downButton->setDisplayOffset(false);
				FCSize size = { 16, 16 };
				downButton->setSize(size);
				return downButton;
			}
			else if (clsid == L"upbutton") {
				FCButton* upButton = new FCButton;
				upButton->setText(L"+");
				upButton->setDisplayOffset(false);
				FCSize size = { 16, 16 };
				upButton->setSize(size);
				return upButton;
			}
		}
		FCDiv* div = dynamic_cast<FCDiv*>(parent);
		if (div) {
			if (clsid == L"hscrollbar") {
				FCHScrollBar* hScrollBar = new FCHScrollBar;
				hScrollBar->setVisible(false);
				FCSize size = { 13, 13 };
				hScrollBar->setSize(size);
				return hScrollBar;
			}
			else if (clsid == L"vscrollbar") {
				FCVScrollBar* vScrollBar = new FCVScrollBar;
				vScrollBar->setVisible(false);
				FCSize size = { 13, 13 };
				vScrollBar->setSize(size);
				return vScrollBar;
			}
		}
		FCGrid* grid = dynamic_cast<FCGrid*>(parent);
		if (grid) {
			if (clsid == L"edittextbox") {
				FCTextBox* editTextBox = new FCTextBox;
				return editTextBox;
			}
		}
		return 0;
	}

    lstring QtHost::getAppPath(){
        return "";
	}

    FCCursors QtHost::getCursor(){
		return FCCursors_Arrow;
	}

    int QtHost::getIntersectRect(FCRect *lpDestRect, const FCRect *lpSrc1Rect, const FCRect *lpSrc2Rect){
        lpDestRect->left = FCTran::maxValue(lpSrc1Rect->left, lpSrc2Rect->left);
        lpDestRect->right = FCTran::minValue(lpSrc1Rect->right, lpSrc2Rect->right);
        lpDestRect->top = FCTran::maxValue(lpSrc1Rect->top, lpSrc2Rect->top);
        lpDestRect->bottom = FCTran::minValue(lpSrc1Rect->bottom, lpSrc2Rect->bottom);
        if(lpDestRect->right > lpDestRect->left && lpDestRect->bottom > lpDestRect->top){
            return 1;
        }
        else{
            lpDestRect->left = 0;
            lpDestRect->right = 0;
            lpDestRect->top = 0;
            lpDestRect->bottom = 0;
            return 0;
        }
	}

    FCPoint QtHost::getTouchPoint(){
		FCPoint mp = m_touchPoint; 
		if (m_native->allowScaleSize()){
			FCSize clientSize = getClientSize();
			if (clientSize.cx > 0 && clientSize.cy > 0){
				FCSize scaleSize = m_native->getScaleSize();
				mp.x = mp.x * scaleSize.cx / clientSize.cx;
				mp.y = mp.y * scaleSize.cy / clientSize.cy;
			}
		}
		return mp;
	}

    FCSize QtHost::getSize(){
        if (m_native->allowScaleSize()){
            return m_native->getScaleSize();
        }
        else{
            return getClientSize();
        }
	}

    int QtHost::getUnionRect(FCRect *lpDestRect, const FCRect *lpSrc1Rect, const FCRect *lpSrc2Rect){
        return 0;
	}

    void QtHost::invalidate(){
		if(!m_virtualMode){
            if(m_objectItem){
                m_objectItem->update();
            }else{
                m_widget->update();
            }
		}
	}

    void QtHost::invalidate(const FCRect& rect){
		if(!m_virtualMode){
           if(m_objectItem){
               m_objectItem->update();
           }else{
              double scaleFactorX = 1, scaleFactorY = 1;
              FCSize clientSize = getClientSize();
              if (m_native->allowScaleSize()){
                  if (clientSize.cx > 0 && clientSize.cy > 0){
                      FCSize scaleSize = m_native->getScaleSize();
                      scaleFactorX = (double)(clientSize.cx) / scaleSize.cx;
                      scaleFactorY = (double)(clientSize.cy) / scaleSize.cy;
                  }
              }
              FCRect newRect = rect;
              if(scaleFactorX != 1 || scaleFactorY != 1){
                  newRect.left = (int)floor(newRect.left * scaleFactorX);
                  newRect.top = (int)floor(newRect.top * scaleFactorY);
                  newRect.right = (int)ceil(newRect.right * scaleFactorX);
                  newRect.bottom = (int)ceil(newRect.bottom * scaleFactorY);
              }
                m_widget->update(newRect.left, newRect.top, newRect.right - newRect.left, newRect.bottom - newRect.top);
           }
		}
	}

    void QtHost::invoke(FCView *view, Object args){
		int seraialID = 0;
		lock();
		m_invokeSerialID++;
		seraialID = m_invokeSerialID;
		m_invokeArgs[seraialID] = args;
		m_invokeViews[seraialID] = view;
        unLock();
	}

    bool QtHost::isKeyPress(char key){
        return false;
	}

    void QtHost::lock(){
	}

    void QtHost::onInvoke(int invokeSerialID){
        Object args = 0;
        FCView *view = 0;
		lock();
		std::map<int, Object>::iterator sIter = m_invokeArgs.find(invokeSerialID);
		if(sIter != m_invokeArgs.end()){
			args = sIter->second;
			m_invokeArgs.erase(sIter);
		}
		std::map<int, FCView*>::iterator sIter2 = m_invokeViews.find(invokeSerialID);
		if(sIter2 != m_invokeViews.end()){
			view = sIter2->second;
			m_invokeViews.erase(sIter2);
		}
		unLock();
		if(view){
			view->onInvoke(args);
		}
	}

    void QtHost::onPaint(const FCRect& rect){
		FCSize displaySize = m_native->getSize();
		double scaleFactorX = 1, scaleFactorY = 1;
		FCSize clientSize = getClientSize();
        if (m_native->allowScaleSize()){
            if (clientSize.cx > 0 && clientSize.cy > 0){
				FCSize scaleSize = m_native->getScaleSize();
                scaleFactorX = (double)(clientSize.cx) / scaleSize.cx;
                scaleFactorY = (double)(clientSize.cy) / scaleSize.cy;
            }
        }
		FCPaint *paint = m_native->getPaint();
		FCRect wRect = {0, 0, clientSize.cx, clientSize.cy};
		paint->setScaleFactor(scaleFactorX, scaleFactorY);
		FCRect clipRect = rect;
        if (clipRect.left < 0)
        {
            clipRect.left = 0;
        }
        if (clipRect.top < 0)
        {
            clipRect.top = 0;
        }
        if (clipRect.right * scaleFactorX > clientSize.cx)
        {
            clipRect.right = (int)(clientSize.cx / scaleFactorX);
        }
        if (clipRect.bottom * scaleFactorY > clientSize.cy)
        {
            clipRect.bottom = (int)(clientSize.cy / scaleFactorY);
        }
        paint->beginPaint(0, wRect, clipRect);
		m_native->onPaint(clipRect);
		paint->endPaint();
	}

    lstring QtHost::paste(){
		return "";
	}

    void QtHost::setAllowOperate(bool allowOperate){
		m_allowOperate = allowOperate;
	}

    void QtHost::setAllowPartialPaint(bool allowPartialPaint){
		m_allowPartialPaint = allowPartialPaint;
	}

    void QtHost::setCursor(FCCursors cursor){
	}

    void QtHost::setTouchPoint(const FCPoint& point){
		m_touchPoint = point;
	}

    void QtHost::showToolTip(const String& text, const FCPoint& mp){
		if (m_toolTip){
            m_toolTip->setNative(m_native);
			m_toolTip->setLocation(mp);
            m_toolTip->setText(text);
            m_toolTip->show();
        }
	}

    void QtHost::startTimer(int timerID, int interval){
	}

    void QtHost::stopTimer(int timerID){
	}

    void QtHost::unLock(){
	}
}
